home *** CD-ROM | disk | FTP | other *** search
Lisp/Scheme | 1985-04-27 | 8.4 KB | 247 lines | [TEXT/MACA] |
- ;+
- ; STEP 1.0 : (C) Copyright 1985 by Gregory Frascadore
- ;
- ; This software may be copied, distributed to others, and modified as long
- ; as it is not sold for profit, and as long as this copyright notice is
- ; retained intact. For further information regarding STEP, contact the
- ; author at:
- ; frascado%umn-cs.CSNET (on CSNET)
- ; 75106,662 (on CompuServe)
- ;-
-
- ;+
- ; STEP 1.0
- ; DESCRIPTION
- ; STEP is an interactive debugging tool for use with XLISP 1.4 . With
- ; modification, STEP may work with later versions of XLISP or with other
- ; lisp systems.
- ;
- ; UPDATE HISTORY
- ; Version 1.0 - Original version, March 1985 by Gregory Frascadore.
- ;
- ;-
-
- ;+
- ; Here is where the global symbols are given values. Global symbols are
- ; distinguished from other symbols by their starting and ending asterisks.
- ; ie *global* . Function parameters start with an asterisk, but do not end
- ; with one ie *foo. Local symbols (like those in do, and let) end in asterisks
- ; ie bar*
- ;-
- (setq *step-inprompt* '? ; Each instep is identified by leading '?'
- *step-outprompt* '= ; Outsteps have leading '='
- *step-count* 0 ; How many steps to make without prompting.
- *step-indent* 0 ; The initial amount of indentation.
- *step-indent-incr* 2 ; How much more to indent at each new level
- *step-keys* nil ; List of breakpoint atoms
- *step-transparent* t ; Flag, determines when to print to user.
- *evalhookfnc* '(lambda (*sexpr) (eval *sexpr)) )
- ; The initial evalhook is a nop function.
-
- ;+
- ; step
- ; Turns on stepping or sets breakpoints.
- ;
- ; format
- ; (step [<atom>]...) -if no atoms are specified, stepping begin immediately.
- ;-
- (defun step (&rest *keys)
-
- (if *keys
- (setq *step-keys* *keys
- *step-transparent* t )
- (setq *step-transparent* nil) )
-
- (setq *step-count* 0
- *step-indent* 0 )
-
- (rplacd *evalhookfnc* (cdr stepper)) ; Set stepper as evalhookfnc
- (setq *evalhook* *evalhookfnc*) t) ; then start intercepting evals.
-
- ;+
- ; nostep
- ; Turns off stepping.
- ;
- ; format
- ; (nostep)
- ; returns t always
- ;-
- (defun nostep ()
- (rplacd *evalhookfnc* '((*sexpr) (eval *sexpr))) t)
-
-
- (defun stepper (*sexpr)
-
- ; If the car of the expression being evaluated is in the breakpoint list
- ; then take the stepper out of transparent mode.
-
- (if (and (consp *sexpr)
- (member (car *sexpr) *step-keys*) )
- (setq *step-transparent* nil))
-
- ; Start indenting at a deeper level. If the indent is in some weird state
- ; restore it to a level 1 indent ie 0 + incr.
-
- (if (<= *step-indent* 0)
- (setq *step-indent* *step-indent-incr*)
- (setq *step-indent* (+ *step-indent-incr* *step-indent*)) )
-
- ; Eval the current *sexpr. If we are at level 1, set a catch we can throw
- ; to from deeper levels. Otherwise just do a simple step-evel. When completing
- ; a level 1 eval, turn off transparency and restore the evalhookfnc if they
- ; were disabled from a deeper level.
-
- (prog1
- (cond ((eql *step-indent* *step-indent-incr*)
- (prog1
- (catch '*step-toplevel* (step-eval *sexpr))
- (setq *step-count* 0)
- (cond ((eql *step-transparent* 'c)
- (setq *step-transparent* nil)
- (rplacd *evalhookfnc* (cdr stepper)) ) ) ) )
-
- (t (step-eval *sexpr)) )
- (setq *step-indent* (- *step-indent* *step-indent-incr*)) ) )
-
-
- (defun step-eval (*sexpr)
-
- ; Eval the current *sexpr. If *step-count* is greater than 0, do not prompt
- ; the user for instructions, but do continue to produce output if not in
- ; transparent mode.
-
- (cond ((zerop *step-count*)
- (if (not *step-transparent*)
- (prog2
- (step-prompt *step-inprompt* *sexpr)
- (step-prompt *step-outprompt* (step-docmd *sexpr))
- (terpri) )
- (evalhook *sexpr stepper nil) ) )
-
- ((> *step-count* 0)
- (setq *step-count* (1- *step-count*))
- (if (not *step-transparent*)
- (prog2
- (progn
- (step-prompt *step-inprompt* *sexpr)(terpri))
- (step-prompt *step-outprompt*
- (evalhook *sexpr stepper nil))(terpri) )
- (evalhook *sexpr stepper nil) ) )
-
- (t (break "%Error, Stepper loses")) ) )
-
-
-
- (defun step-docmd (*sexpr)
-
- ; If the *sexpr is an atom, don't bother asking the user what to do. Just echo
- ; the atom and its value. If its not an atom, ask the user what to do until
- ; he gives you a legal responce that either continues or aborts the evaluation.
-
- (do* (cmd* (value* (cond ((atom *sexpr) (terpri) (eval *sexpr))
- (t '*unbound*) )))
- ((cond ((boundp 'value*) t)
- (t (setq cmd* (step-getcmd)) nil) )
- value*)
-
- (case cmd*
-
- '(? (step-help))
-
- '(+ (let ((key* (read)))
- (if (atom key*)
- (setq *step-keys*
- (cons key* *step-keys*) )
- (step-huh?) ) ))
-
- '(- (let ((key* (read)))
- (if (atom key*)
- (setq *step-keys*
- (remove key* *step-keys*) )
- (step-huh?) ) ))
-
- '(b (break "STEP BREAK, type 'continue' or 'quit' when done"))
-
- '(c (setq *step-transparent* 'c)
- (setq value* (evalhook *sexpr stepper nil)) )
-
- '(e (throw '*step-toplevel* t))
-
- '(g (rplacd *evalhookfnc* '((*sexpr) (eval *sexpr)))
- (setq *step-transparent* 'c)
- (setq value* (eval *sexpr)) )
-
- '(h (step-help))
-
- '(n (setq value* (eval *sexpr)))
-
- '(q (setq *step-keys* nil)
- (rplacd *evalhookfnc* '((*sexpr) (eval *sexpr)))
- (throw '*step-toplevel* t) )
-
- '(s (setq value* (evalhook *sexpr stepper nil)))
-
- '(x (throw '*step-toplevel* t) )
-
- '(t (cond ((numberp cmd*)
- (setq *step-count* cmd*)
- (setq value* (evalhook *sexpr stepper nil)) )
- (t (step-huh?)) ) ) ) ) )
-
-
-
- (defun step-getcmd ()
-
- ; Since XLISP normally prompts '>' when asking for input, we add another
- ; '>' here to distinguish a stepper prompt. ie stepper prompts >>
-
- (princ " >")
- (read))
-
- (defun step-prompt (*prompt *sexpr)
-
- ; Here we print the *sexpr with a informative leading character (usually
- ; either ? or = ). If the *sexpr is long then we won't print the whole thing
- ; just an outline which abbreviates nested lists as (...)
-
- (spaces *step-indent*)
- (princ *prompt)
-
- (let ((len (flatc *sexpr)))
- (cond ((<= (- len *step-indent*) 75)
- (princ *sexpr) )
- (t (short-princ *sexpr)) ) )
- *sexpr )
-
-
- (defun step-help ()
-
- (princ "Here is a summary of the available commands:\n")
- (princ " s - steps once more\n")
- (princ " ? - prints this help\n")
- (princ " b - enter a break loop\n")
- (princ " c - continue program until next breakpoint\n")
- (princ " e - exit program, return to toplevel\n")
- (princ " g - go on without further stepping interruptions\n")
- (princ " h - prints this help\n")
- (princ " n - continue stepping, but no deeper\n")
- (princ " q - quit program, clear breakpoints, return to toplevel\n")
- (princ " x - exit, same as e\n")
- (princ " # - make # steps at once\n")
- (princ " + <atom> - add this atom to list of breakpoints\n")
- (princ " - <atom> - remove this atom from list of breakpoints\n" ) )
-
-
- (defun step-huh? ()
- (princ "Huh? Type h or ? for help ") )
-
-
- ;+
- ; The End.
- ;-
-
-
-
-
-
-